package ComoViajo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;


public abstract class Estacion implements EstacionInterface{
	protected static final int TIEMPO_COMBINACION_SUBTE_TREN=5;
	protected static final int TIEMPO_COMBINACION_TREN_TREN=6;
	protected static final int TIEMPO_COMBINACION_SUBTE_SUBTE = 4;
	
	protected Collection<Estacion> estacionesConectadas=new ArrayList<Estacion>();
	protected ArrayList<EstacionInterface> estacionesCercanas=new ArrayList<EstacionInterface>();
	
	
	protected Linea linea;
	protected String nombre;
	protected Direccion direccion;
	
	protected EstacionInterface estacionSiguiente = null;
	protected EstacionInterface estacionAnterior = null;
	
	public Estacion(String nombre, String linea){
		this.nombre=nombre;
		this.linea=Linea.getInstance(linea);
	}
	
	public Estacion(String nombre, String linea,Direccion direccion){
		this.nombre=nombre;
		this.linea=Linea.getInstance(linea);
		this.estacionesCercanas = FactoryModuloExterno.getMapaDeTransporte().getTransportesCercanos(direccion);
		this.direccion=direccion;
	}
	
	public void addEstacionQueCombina(Estacion estacion){
		if(!this.estacionesConectadas.contains(estacion)){
			this.estacionesConectadas.add(estacion);
			estacion.estacionesConectadas.add(this);
		}
	}
	
	
	public String toString(){
		return this.linea.toString()+this.nombre;
	}

	
	abstract protected int getTiempoTransbordo(EstacionTren estacionTren);
	abstract protected int getTiempoTransbordo(EstacionSubte estacionSubte);

	
	// Acostumbrarse a poner setters y getters
	
	public String getLinea() {
		return this.linea.toString();
	}

	// Acostumbrarse a poner setters y getters
	protected String getNombre() {
		return this.nombre;
	}	
	
	/**
	 * Compara si la estacion es la misma. 
	 * Si son iguales es porque tienen la misma linea y el mismo nombre
	 * @param aComparar
	 * @return
	 */

	public boolean comparate(String lineaAComparar, String nombreAComparar) {
		return this.getNombre().equals(nombreAComparar) && this.getLinea().equals(lineaAComparar);
	}

	
	public void conectar(EstacionInterface estacionAnterior, EstacionInterface estacionSiguiente) {
		this.estacionAnterior=estacionAnterior;
		this.estacionSiguiente=estacionSiguiente;
	}
	
	
	private ArrayList<HashMap<String, EstacionInterface>> getEstacionesQueCombinan(EstacionInterface estacionDestino,ArrayList<HashMap<String, EstacionInterface>> combinaciones, boolean irHAciaAdelante){
		EstacionInterface estacionQueCombina,estacionActual;
		HashMap<String, EstacionInterface> combinacion;
		
		if(irHAciaAdelante){
			estacionActual=this;
		}else{
			estacionActual=this.estacionAnterior;
		}
		
		while (estacionActual!=null) {
			if((estacionQueCombina=estacionActual.getEstacionDeCombinacion(estacionDestino))!=null){
				combinacion=new HashMap<String, EstacionInterface>();
				combinacion.put("combinacionEstacionOrigen", estacionActual);
				combinacion.put("combinacionEstacionDestino", estacionQueCombina);
				
				combinaciones.add(combinacion);
			}
			
			if(irHAciaAdelante){
				estacionActual=estacionActual.getEstacionSiguiente(null);
			}else{
				estacionActual=estacionActual.getEstacionAnterior();
			}
		}
				
		return combinaciones;
	}
	
	// LONG CODE huele feo. Refactorizar. Pueden hacer extract method de ambos while
	// se refactorizo y se implemento el metodo getEstacionesQueCombinan
	public ArrayList<HashMap<String, EstacionInterface>> getEstacionesQueCombinanCon(EstacionInterface estacionDestino) {
		ArrayList<HashMap<String, EstacionInterface>> combinaciones=new ArrayList<HashMap<String, EstacionInterface>>();
		
		combinaciones=this.getEstacionesQueCombinan(estacionDestino, combinaciones, true);
		
		combinaciones=this.getEstacionesQueCombinan(estacionDestino, combinaciones, false);
				
		return combinaciones;
		
	}

	public EstacionInterface getEstacionDeCombinacion(EstacionInterface estacionDestino) {
		for (EstacionInterface e : this.estacionesConectadas) {
			if(e.estaEnLaMismaLineaQue(estacionDestino)){
				return e;
			}
		}
		
		for (EstacionInterface e : this.estacionesCercanas) {
			if(e.estaEnLaMismaLineaQue(estacionDestino)){
				return e;
			}
		}
		
		return null;
	}

	public EstacionInterface getEstacionAnterior() {
		return estacionAnterior;
	}
	
	public EstacionInterface getEstacionSiguiente(EstacionInterface estacionDestino) {
		return estacionSiguiente;
	}

	public ArrayList<EstacionInterface> getEstacionesCercanas() {
		return this.estacionesCercanas;
	}


	public boolean estaEnLaMismaLineaQue(EstacionInterface medioDeTransporte) {
		return this.linea.toString().equals(medioDeTransporte.getLinea());
	}
	
	public void notificar(Viaje viaje) {
		this.linea.notificar(viaje);
	}
	
	public int getUso() {
		return this.linea.getUso();
	}
	
	public Direccion getDireccion(){
		return this.direccion;
	}
}
